package com.css.fxfzaqbz.modules.callJcData.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzaqbz.base.response.RestResponse;
import com.css.fxfzaqbz.constants.FxfzConstants;
import com.css.fxfzaqbz.constants.YNEnum;
import com.css.fxfzaqbz.modules.base.service.HypergraphService;
import com.css.fxfzaqbz.modules.callJcData.constonts.RedisKeyConstants;
import com.css.fxfzaqbz.modules.callJcData.entity.TableFieldDesc;
import com.css.fxfzaqbz.modules.callJcData.exception.ShpFieldException;
import com.css.fxfzaqbz.modules.callJcData.param.DataVersionPageParam;
import com.css.fxfzaqbz.modules.callJcData.param.SysDataVersionPageParam;
import com.css.fxfzaqbz.modules.callJcData.result.ParsingResult;
import com.css.fxfzaqbz.modules.callJcData.vo.IdsVO;
import com.css.fxfzaqbz.modules.callJcData.vo.ListVo;
import com.css.fxfzaqbz.modules.callJcData.vo.SitePhotoVO;
import com.css.fxfzaqbz.modules.data.entity.Site;
import com.css.fxfzaqbz.modules.data.queryParams.SiteQueryParams;
import com.css.fxfzaqbz.modules.callJcData.repository.SiteRepository;
import com.css.fxfzaqbz.modules.callJcData.service.SiteService;
import com.css.fxfzaqbz.modules.supergraph.exception.CustomException;
import com.css.fxfzaqbz.modules.threadpool.ThreadPoolManage;
import com.css.fxfzaqbz.util.*;
import com.css.fxfzaqbz.util.fileParsing.shp.ShpAnalyticUtil;
import com.css.fxfzaqbz.web.PlatformSessionContext;
import com.css.fxfzaqbz.zcpt.sys.entity.SUser;
import com.css.fxfzaqbz.zcpt.sys.service.SUserService;
import com.css.fxfzaqbz.zcpt.sys.service.SysAreaService;
import com.css.fxfzaqbz.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class SiteServiceImpl implements SiteService {
    @Resource
    SiteRepository siteRepository;

    @Resource
    StringRedisTemplate stringRedisTemplate;


    @Resource
    private SUserService sUserService;
    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysAreaService sysAreaService;
    @Resource
    private HypergraphService hypergraphService;

    @Override
    public Site updateSite(Site site,String userID) {
        site.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        site.setUpdateUser(userID);
        return siteRepository.updateSite(site);
    }

    @Override
    public Site saveSite(Site site , HttpServletRequest request) {
        site.setDataVersion(getVersionCodeSiteNum());
        site.setSsId(UUIDGenerator.getUUID());
        site.setDelFlag(YNEnum.Y.toString());
        site.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        site.setUploadTime(PlatformDateUtils.getCurrentTimestamp());
        Site site1 = siteRepository.saveSite(site);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_site"));
        return site1;
    }


    @Override
    public Map<String,Object> getAllSite(SiteQueryParams queryParams) {
        return siteRepository.getAllSiteParams(queryParams);
    }

    @Override
    public Site getSiteById(String id) {

        return siteRepository.getSiteById(id);
    }

    @Override
    public boolean getSiteByName(String name) {
        boolean flag = true ;
        List<Site> sites = siteRepository.getSiteByName(name);
        if(sites.size()==0){
            flag = false;
        }
        return flag;
    }

    @Override
    public void deleteSites(List<String> ids,String userId) {
        Timestamp timestamp = PlatformDateUtils.getCurrentTimestamp();
        siteRepository.deleteSitesById(ids,timestamp,userId);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_site"));

    }

    @Override
    public List<Site> getAll() {

        return siteRepository.getAll();
    }

    @Override
    public void importExcel(MultipartFile file) throws IOException {
        List<Site> sites = FileUtil2.importExcel(file, Site.class);
        System.out.println(sites.toString());
        for(int i = 0 ; i<sites.size();i++){
            sites.get(i).setSsId(UUIDGenerator.getUUID());
            sites.get(i).setDelFlag(YNEnum.Y.toString());
            sites.get(i).setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        }
        siteRepository.importExcel(sites);
    }

    @Override
    public List<Site> getSiteDataView(SysDataVersionPageParam sysDataVersionPageParam) {
        return siteRepository.getSiteDataView(sysDataVersionPageParam);
    }

    @Override
    public RestResponse saveShpTemporaryData(ParsingResult shpData) throws ShpFieldException {
        try {
        //生成临时版本号
        String dataVersion = UUID.randomUUID().toString().replaceAll("-", "");
        List<Site> list = getList(shpData.getShpList(), dataVersion);
        if (list==null){
            return RestResponse.fail("字段数量不符合要求");
        }
        siteRepository.byShpBatchSave(list);
        ListVo listVo=new ListVo("1","1",dataVersion,"重点场所",null,list);
        return RestResponse.succeed(listVo);
    } catch (ShpFieldException e) {
        log.error(e.getMessage(), e);
        return RestResponse.fail(e.getMessage());
    } catch (IndexOutOfBoundsException e1) {
        log.error(e1.getMessage(), e1);
        return RestResponse.fail("字段数量不符合要求");
    }
    }

    @Override
    public void deleteByVersion(String versionCode) {
        siteRepository.deleteByVersion(versionCode);
    }

    @Override
    public void updateByLsVersion(String tempVersionCode, String versionCode,Integer sf) {
        siteRepository.updateByLsVersion(tempVersionCode,versionCode,sf);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_site"));

    }

    @Override
    public List<Site> getYwData(String versionCode) {
        return siteRepository.getYwData(versionCode);
    }

    @Override
    public void uploadSitePhotos(SitePhotoVO sitePhotoVO) {
        siteRepository.uploadSitePhotos(sitePhotoVO);
    }

    @Override
    public List<TableFieldDesc> getByDictItemId(String dictItemId) {
        return siteRepository.getByDictItemId(dictItemId);
    }

    @Override
    public void submitYwData(IdsVO idss) {
        siteRepository.submitYwData(idss.getIds());
    }

    @Override
    public void updateLs(String versionCode, String tempVersionCode) {
        siteRepository.updateLs(versionCode,tempVersionCode);
        ThreadPoolManage.exeBizThreadPoolExecutor.execute(()->hypergraphService.getWorkspaceReload("sys_site"));

    }

    @Override
    public RestResponse getFyYwData(DataVersionPageParam dataVersionPageParam) {

        String role = getRole();
        return siteRepository.getFyYwData(dataVersionPageParam,role);
    }

    @Override
    public List<Site> getSiteNumByVersion(String versionCode) {
        return siteRepository.getSiteNumByVersion(versionCode);
    }

    private List<Site> getList(List<List<Object>> shpList, String dataVersion) throws ShpFieldException {
        String userID = PlatformSessionContext.getUserID(); // 获取当前登录用户
        ArrayList<Site> arrayList = new ArrayList<>();
        for (int i = 0; i < shpList.size(); i++) {
            List<Object> list = shpList.get(i);
         /*   if (list.size()!=18){
                return null;
            }*/
            Site obj = new Site();
            //临时版本号
            obj.setDataVersion(dataVersion);
            //当前用户
            obj.setCreateUser(userID);
            obj.setIfSubmit(YNEnum.N.toString());
            obj.setSsNumber(getVersionCodeSiteNum());
            obj.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            obj.setDelFlag(YNEnum.N.toString());
            obj.setUploadTime(PlatformDateUtils.getCurrentTimestamp());
            obj.setSsId(UUID.randomUUID().toString().replaceAll("-", ""));
            obj.setZdNum(list.size());
            obj.setGeom(list.get(0).toString());
            obj.setSsProvince(ShpAnalyticUtil.getStringVal(list.get(1),"省",true));
            obj.setSsCity(ShpAnalyticUtil.getStringVal(list.get(2),"市",true));
            obj.setSsCounties(ShpAnalyticUtil.getStringVal(list.get(3),"区（县）",true));
            obj.setSsLongitude(ShpAnalyticUtil.getDoubleVal(list.get(4),"经度",true));
            obj.setSsLatitude(ShpAnalyticUtil.getDoubleVal(list.get(5),"纬度",true));
            obj.setSsJglx(ShpAnalyticUtil.getStringVal(list.get(6),"结构类型",true));
            obj.setSsJzwmc(ShpAnalyticUtil.getStringVal(list.get(7),"建筑物名称",true));
            obj.setSsJznd(ShpAnalyticUtil.getStringVal(list.get(8),"建造年代",true));
            obj.setSsCs(ShpAnalyticUtil.getDoubleVal(list.get(9),"层数",true));
            obj.setSsCg(ShpAnalyticUtil.getDoubleVal(list.get(10),"层高",true));
            obj.setSsYt(ShpAnalyticUtil.getStringVal(list.get(11),"用途",true));
            obj.setSsPlmgzcd(ShpAnalyticUtil.getStringVal(list.get(12),"平立面规则程度",true));
            obj.setSsSfbz(ShpAnalyticUtil.getStringVal(list.get(13),"设防标准",true));
            obj.setSsWglb(ShpAnalyticUtil.getStringVal(list.get(14),"屋盖类别",false));
            obj.setSsJzgztd(ShpAnalyticUtil.getStringVal(list.get(15),"建构造特点",true));
            obj.setSsDwmjzj(ShpAnalyticUtil.getDoubleVal(list.get(16),"单位面积造价",true));
            obj.setSsBz(ShpAnalyticUtil.getStringVal(list.get(17),"备注",false));
            arrayList.add(obj);
        }
        return arrayList;
    }


    private String getVersionCodeSiteNum() {
        return this.getVersionCode();
    }

    public synchronized String getVersionCode() {
        String dataVersionCodeSerialNumber = stringRedisTemplate.opsForValue().get(RedisKeyConstants.DATA_SITE_NUMBER_KEY);
        if (StringUtils.isBlank(dataVersionCodeSerialNumber)) {
            dataVersionCodeSerialNumber = "001";
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            String t = String.valueOf(Integer.parseInt(dataVersionCodeSerialNumber) + 1);
            for (int i = t.length(); i < 5; i++) {
                stringBuilder.append("0");
            }
            dataVersionCodeSerialNumber = stringBuilder.append(t).toString();
        }
        stringRedisTemplate.opsForValue().set(RedisKeyConstants.DATA_SITE_NUMBER_KEY, dataVersionCodeSerialNumber);
        stringRedisTemplate.expireAt(RedisKeyConstants.DATA_SITE_NUMBER_KEY, Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toInstant(ZoneOffset.of("+8"))));
        return DateUtil.format(new Date(), "yyyyMMdd") +"ZD"+ dataVersionCodeSerialNumber;
    }



    public String getRole() {
        String userId = PlatformSessionContext.getUserID();
        String user = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        String role = sysRoleService.getRoleByUserId(userId);
        List<Map> maps = JSONObject.parseArray(role, Map.class);//一个人可能有多个角色
        //当前登录人所有的角色
        StringBuilder roles = new StringBuilder();
        for (int i = 0; i < maps.size(); i++) {
            Map map = maps.get(i);
            roles.append(map.get("roleCode") + ",");
        }
        String allRole = roles.toString();

        //如果所有角色包括国家级管理员
        if (allRole.contains(FxfzConstants.AQBZ_GJJGLY_ROLE)) {
            return "0";
        }
        //如果所有角色包括省级管理员
        if (allRole.contains(FxfzConstants.AQBZ_SJGLY_ROLE)) {
            if (PlatformObjectUtils.isEmpty(sUser.getProvinceId())) {
                throw new CustomException("请完善当前登陆人所属省市信息");
            }
            String areaName = sysAreaService.getAreaNameByAreaId(sUser.getProvinceId());
            return areaName;
        }
        return "1";
    }
}